/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package shaman.storage;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import shaman.dialog.util.ExtensionFileFilter;
import shaman.storage.api.Configurable;

/**
 *
 * @author Shaman
 */
@XStreamAlias("rule")
public class Rule implements Configurable {
        
    public enum RuleTypes
    {
        MASK,
        REGEXP,
        SCRIPT
    }

    @XStreamAsAttribute
    private boolean addable = true;
    private boolean showInSubfolders = true;
    private RuleTypes type = RuleTypes.MASK;
    private String value = "";
    @XStreamAsAttribute
    private String comment = "";
    @XStreamAsAttribute
    private String directory = "";

    public Rule() {
    }

    public boolean showInSubfolders()
    {
        return showInSubfolders;
    }

    public void setShowInSubfolders(boolean show)
    {
        showInSubfolders = show;
    }

    public boolean isAddable() {
        return addable;
    }

    public void setAddable(boolean Addable) {
        this.addable = Addable;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String Comment) {
        this.comment = Comment;
    }

    public String getDirectory() {
        return directory;
    }

    public void setDirectory(String Directory) {
        this.directory = Directory;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String Value) {
        this.value = Value;
    }
    
    private void getFolderFiles(List<String> fileList, String path, boolean showSubFolders) throws IOException
    {
        if (fileList == null)
            throw new InvalidParameterException();
        if (path.charAt(path.length()-1) != File.separatorChar)
                path += File.separatorChar;
        File file = new File(path);
        if (file.isDirectory())
        {
            //Получение списка всех файлов в текущей директории
            File[] incFiles = file.listFiles(new FileFilter() {                    

                    Pattern pattern = null;

                    public boolean accept(File f) {
                        if (f.isDirectory())
                            return true;
                        if (getRuleType() == RuleTypes.MASK)
                        {
                            if (pattern == null)
                                pattern = Pattern.compile(ExtensionFileFilter.getPatternByFilemask(getValue()));
                            return pattern.matcher(f.getAbsolutePath()).lookingAt();
                        }
                        else
                        {
                            if (pattern == null)
                                pattern = Pattern.compile(getValue());
                            return pattern.matcher(f.getAbsolutePath()).lookingAt();
                        }
                        
                    }
                });
            //Обработка подпапок
            if (incFiles != null)
                for (int i = 0; i < incFiles.length; i++)
                {
                    if (incFiles[i].isDirectory())
                    {
                        if (showSubFolders)
                        {
                            //System.out.println("try look in subfolder: " + path + incFiles[i].getName());
                            if (fileList != null)
                                getFolderFiles(fileList, path + incFiles[i].getName() + File.separatorChar, showSubFolders);
                            //else
                                //System.out.println("fileList is null");
                        }
                    }
                    else
                    {
                        //System.out.println("add file " + path + incFiles[i].getName());
                        fileList.add(path + incFiles[i].getName());
                    }
                }
        }
    }
    
    public List<String> getFileList() throws IOException
    {
        List<String> fileList = new ArrayList<String>();
        getFolderFiles(fileList, getDirectory(), showInSubfolders);
        return fileList;
    }

    public RuleTypes getRuleType()
    {
        return type;
    }

    public String getRuleTypeName()
            throws InvalidParameterException
    {
        RuleTypes RuleType = getRuleType();
        if (RuleType == RuleTypes.MASK)
            return "Маска";
        else if (RuleType == RuleTypes.REGEXP)
            return "Регулярное выражение";
        else if (RuleType == RuleTypes.SCRIPT)
            return "Скрипт";
        else 
            throw new InvalidParameterException();
    }
    
    public static RuleTypes getRuleTypeByName(String TypeName)
            throws InvalidParameterException
    {
        if (TypeName.equalsIgnoreCase("Маска"))
            return RuleTypes.MASK;
        else if (TypeName.equalsIgnoreCase("Регулярное выражение"))
            return RuleTypes.REGEXP;
        else if (TypeName.equalsIgnoreCase("Скрипт"))
            return RuleTypes.SCRIPT;
        else 
            throw new InvalidParameterException();   
    }

    public void setRuleType(RuleTypes type)
    {
        this.type = type;
    }

    public boolean hasConfigForm()
    {
        return true;
    }

    public boolean showConfigForm(java.awt.Frame parent)
    {
        DialogRuleEdit ruleForm = new DialogRuleEdit(parent, true, this);
        ruleForm.setModal(true);
        ruleForm.setLocationRelativeTo(parent);
        ruleForm.setVisible(true);
        return true;
    }

    public List<String> getPropertyNames()
    {
        List<String> names = new ArrayList<String>();
        names.add("type");
        names.add("value");
        names.add("comment");
        names.add("directory");
        return names;
    }

    public String getPropertyValue(String name)
            throws InvalidParameterException
    {
        if (name.equalsIgnoreCase("type"))
            return getRuleTypeName();
        else if (name.equalsIgnoreCase("comment"))
            return getComment();
        else if (name.equalsIgnoreCase("directory"))
            return getDirectory();
        else if (name.equalsIgnoreCase("value"))
            return getValue();
        else
            throw new InvalidParameterException();
    }

    public List<String> getPropertyValues(String name)
            throws InvalidParameterException
    {
        if (name.equalsIgnoreCase("type"))
        {
            List<String> values = new ArrayList<String>();
            values.add("Маска");
            values.add("Регулярное выражение");
            //values.add("Скрипт");
            return values;
        }
        else if (name.equalsIgnoreCase("comment"))
            return null;
        else if (name.equalsIgnoreCase("directory"))
            return null;
        else if (name.equalsIgnoreCase("value"))
            return null;
        else
            throw new InvalidParameterException();
    }

    public void setPropertyValue(String name, String value)
            throws InvalidParameterException
    {
       if (name.equalsIgnoreCase("type"))
        {
            setRuleType(getRuleTypeByName(value));
        }
        else if (name.equalsIgnoreCase("comment"))
            setComment(value);
        else if (name.equalsIgnoreCase("directory"))
            setDirectory(value);
        else if (name.equalsIgnoreCase("value"))
            setValue(value);
        else
            throw new InvalidParameterException();
    }
}
